<template>
    <div>
        <h4>- 可以理解Generator 函数是一个状态机，封装了多个内部状态，返回一个遍历器对象，可以依次遍历 Generator 函数内部的每一个状态</h4>
        <pre>
    <code>
        function* helloWorldGenerator() { //* 号表示 generator 函数
            yield 'hello';
            yield 'world';      //函数体内部使用yield表达式，定义不同的内部状态
            return 'ending';  //该函数有三个状态：hello，world 和 return 语句（结束执行）
        }

        var hw = helloWorldGenerator(); //！！调用 Generator 函数后，该函数并不执行，返回不是函数运行结果，而是一个指向内部状态的指针对象（遍历器对象）
    </code>
        </pre>
        <p>Generator 函数是分段执行的，yield表达式是暂停执行的标记，而next方法可以恢复执行</p>
        <pre>
    <code>
        hw.next()
        // { value: 'hello', done: false }

        hw.next()
        // { value: 'world', done: false }

        hw.next()
        // { value: 'ending', done: true }

        hw.next()
        // { value: undefined, done: true }
    </code>
        </pre>
        <p><b>generator 只有调用了 next() 方法才会执行！</b></p>
        <p>yield表达式只能用在 Generator 函数里面，注意在generator函数中的普通函数也是不能使用yield的；yield表达式如果用在另一个表达式之中，必须放在圆括号里面</p>
        <p>可以把 Generator 赋值给对象的Symbol.iterator属性，从而使得该对象具有 Iterator 接口，可以被...运算符遍历了</p>
        <h4>- next 方法的参数</h4>
        <p>yield表达式本身没有返回值，或者说总是返回undefined。next方法可以带一个参数，该参数就会被当作<b>上一个(所以第一个next()传惨是无效的)</b>表达式的返回值，这使得<b>有办法在 Generator 函数开始运行之后，继续向函数体内部注入值，从而调整函数行为</b></p>
        <h4>- for...of 循环 无须 next()方法 就可以遍历Generator 函数运行时生成的Iterator对象</h4>
        <p>注意：一旦next方法的返回对象的done属性为true，for...of循环就会中止，且不包含该返回对象：</p>
        <pre>
    <code>
        function* foo() {
            yield 1;
            yield 2;
            yield 3;
            yield 4;
            yield 5;
            return 6;
        }

        for (let v of foo()) {
            console.log(v);
        }
        // 1 2 3 4 5 不含 6
    </code>
        </pre>
        <h4>- Generator.prototype.throw() generator 函数返回的遍历器对象，都有一个throw方法，可以在函数体外抛出错误，然后在 Generator 函数体内捕获</h4>
        <p>不要混淆遍历器对象的throw方法和全局的throw命令，后者只能被函数体外的catch语句捕获</p>
        <p>throw方法抛出的错误要被内部捕获，前提是必须至少执行过一次next方法</p>
        <p>！！！throw方法被捕获以后，会附带自动执行下一条yield表达式</p>
        <p>一旦 Generator 执行过程中抛出错误，且没有被内部捕获，就不会再执行下去了</p>
        <h4>- Generator.prototype.return() Generator 函数返回的遍历器对象，还有一个return方法，可以返回给定的值，并且终结遍历 Generator 函数。</h4>
        <p>不提供参数，则返回值的value属性为undefined</p>
        <p>如果 Generator 函数内部有try...finally代码块，且正在执行try代码块，那么return方法会推迟到finally代码块执行完再执行</p>
        <h4>- next()、throw()、return()的作用都是让 Generator 函数恢复执行，并且使用不同的语句替换yield表达式</h4>
        <h4>- yield* 表达式 用来在一个 Generator 函数里面执行另一个 Generator 函数</h4>
        <p>yield*后面的 Generator 函数（没有return语句时），等同于在 Generator 函数内部，部署一个for...of循环；在有return语句时，则需要用var value = yield* iterator的形式获取return语句的值</p>
        <p>任何数据结构只要有 Iterator 接口，就可以被yield*遍历</p>
        <h4>- 作为对象属性的 Generator 函数 </h4>
        <code>let obj={* foo(){...}} 或者 let obj={foo: function* (){...}}</code>
        <h4>- Generator 函数的this</h4>
        <p>Generator 函数总是返回一个遍历器，这个遍历器是 Generator 函数的实例，也继承了 Generator 函数的prototype对象上的方法，但是<b>this和new都不能使用</b></p>
        <p>变通方法：</p>
        <pre>
    <code>
        function* gen() {
            this.a = 1;
            yield this.b = 2;
            yield this.c = 3;
        }

        function F() {
            return gen.call(gen.prototype);
        }

        var f = new F();

        f.next();  // Object {value: 2, done: false}
        f.next();  // Object {value: 3, done: false}
        f.next();  // Object {value: undefined, done: true}

        f.a // 1
        f.b // 2
        f.c // 3
    </code>
        </pre>
        <h4>- 应用</h4>
        <ul>
            <li>异步操作同步化</li>
            <li>解决地狱回调 控制流管理</li>
            <li>部署 Iterator 接口</li>
            <li>作为数据结构</li>
        </ul>
    </div>
</template>

<script>
export default {
    
}
</script>

<style scoped>

</style>